<?php

namespace App\Repository\Repositories;

use App\Models\IntegralRecord;
use App\Models\User;
use App\Models\UserSign;
use App\Repository\RepositoryInterface\SignInterface;
use Illuminate\Support\Facades\Redis;

class SignRepositories implements SignInterface
{



    /**
     * 活动签到存储用户id
     * mysql签到与redis签到区别
     *
     * 签到页面数据
     * @param $uid
     * @return mixed|void
     */
    public function checkPage($uid)
    {
        $month = date('Ym');
        $day = date('d');
        $i = 0;
        $signKey = $uid . ':' . $month;
        $sign = Redis::getbit($signKey, $day);
        $user = (new User())->where('uid',$uid)->first()->toarray();
        $signum = Redis::bitcount($signKey,0,-1);
        if ($sign == 1) {
            //连续签到次数
            $min = self::getNum($uid, $month, $day,$i);
            return success('查询成功',['num' => $min,'day' => date('d'),'integral' => $user['integral'],'year' => date('Y'),'month' => date('m'),'user' => $user,'sign_num' => $signum]);
        }
        return success('查询成功',['num' => $i,'day' => date('d'),'integral' => $user['integral'],'year' => date('Y'),'month' => date('m'),'user' => $user,'sign_num' => $signum]);
    }

    /**
     * 签到
     * @param $uid
     * @return false|string
     */
    public function Sign($uid)
    {
        //获取当前时间
        $now = date('Ym');
        $day = date('d'); //04
        //拼接bitmap的key
        $key = $uid.':'.$now;  //"1:202207"
        $date = Redis::getbit($key,$day);
        if($date) return success('今天已签到');
        $lastDay = date("d", strtotime("-1 day"));  //"02"
        $lastDate = Redis::getbit($key,$lastDay);
        $user = User::where('uid',$uid)->first();
        if($lastDate){
            if ($user['sign_num'] == 5 || $user['sign_num'] == 11 || $user['sign_num'] == 17){
                $getIntegral = 80;
            }elseif($user['sign_num'] >= 3){ //3 天以上均送 30 积分等
                $getIntegral = 30;
            }else{
                $getIntegral = 10;
            }
            $i = 1;
            $num = self::getNum($uid, $now, $lastDay,$i);
            $integralFen = $user['integral'] + $getIntegral;
            $result = User::where('uid',$uid)->update(['sign_num' => $num,'integral' => $integralFen]);
            if (!$result) return error('签到失败');
            $signRes = UserSign::insert(['uid' => $uid,'title' => "用户第$num 次签到",'number' => $getIntegral,'balance' => $integralFen,'add_time' => time()]);
            if (!$signRes) return error('签到失败');
            IntegralRecord::insert(['uid' => $uid,'integral_source' => '2','integral_increase' => $getIntegral,'add_time' => time()]);
            $signum = Redis::bitcount($key,0,-1);
            Redis::setbit($key,$day,1);
            return success("您已连续签到$num 天，已得积分$integralFen 分",['num' => $num,'day' => date('d'),'integral' => $integralFen,'sign_num' => $signum]);
        }
        //如果连续签到中断，则重置计数，每月初重置计数
        $getIntegral = 10;
        $num = 1;
        $result = User::where('uid',$uid)->update(['sign_num' => $num,'integral' => $user['integral'] + $getIntegral]);
        if (!$result) return error('签到失败');
        $signRes = UserSign::insert(['uid' => $uid,'title' => "用户$uid 签到",'number' => $getIntegral,'balance' => $user['integral'] + $getIntegral,'add_time' => time()]);
        if (!$signRes) return error('签到失败');
        IntegralRecord::insert(['uid' => $uid,'integral_source' => 1,'integral_increase' => $getIntegral,'add_time' => time()]);
        $user = (new User())->where('uid',$uid)->first()->toarray();
        $signum = Redis::bitcount($key,0,-1);
        Redis::setbit($key,$day,1);
        return success('签到成功',['num' => $num,'day' => date('d'),'integral' => $user['integral'] + $getIntegral,'sign_num' => $signum]);
    }

    /**
     * 补签
     * @param $uid
     * @param $date
     * @return false|mixed|string
     */
    public function retroactive($uid, $date)
    {
        //获取今天的时间
        $now = date('Ymd');
        if ($date >= $now) return error('补签的日期不能大于等于今天');
        //获取要补签的时间
        $day = substr($date, 6, 2);
        $month = substr($date, 0, 6);
        $key = $uid . ':' . $month;
        $sign = Redis::getbit($key, $day); //0
        if ($sign == 1) return error('你已经签到过了不需要补签');
        Redis::setbit($key, $day, 1);
        //查询用户信息
        $user = User::where('uid',$uid)->first()->toarray();
        //每次补签需花费30积分
        $fire = 30;
        if($user['integral'] < $fire) return error('您的积分不足，不符合补签的条件');
        $integral = $user['integral'] - $fire;
        $month = date('Ym');
        $day = date('d') - 1;
        $signKey = $uid . ':' . $month;
        $sign = Redis::getbit($signKey, $day);
        if ($sign == 1) {
            //连续签到次数
            $i = 1;
            $i = self::getNum($uid, $month, $day,$i);
            User::where('uid',$uid)->update(['integral' => $integral,'sign_num' => $i]);
        }
        $signRes = UserSign::insert(['uid' => $uid,'title' => "用户$uid 补签",'number' => 0,'balance' => $integral,'add_time' => time()]);
        if (!$signRes) return error('签到失败');
        IntegralRecord::insert(['uid' => $uid,'integral_end' => 2,'integral_reduce' => $fire,'add_time' => time()]);
        $signum = Redis::bitcount($key,0,-1);
        return success("您补签成功",['num' => $i,'day' => date('d'),'integral' => $integral,'sign_num' => $signum]);
    }

    /**
     * 计算连续签到的天数
     * @param $uid
     * @param $date
     * @param $day
     * @param $i
     * @return false|int|mixed|string
     */
    public static function getNum($uid, $date, $day,&$i)
    {
        try {
            $key = $uid . ':' . $date;
            $sign = Redis::getbit($key, $day);
            if ($sign == 1) {
                $i ++;
                if ($day - 1 > 0) {
                    self::getNum($uid, $date, $day - 1,$i);
                }
//                else{
//                    dd(123);
//                    $time = strtotime($date . '0' . $day) - 86400;
//                    $mytime = date('Ymd', $time);
//                    $day = substr($mytime, 6, 2);
//                    $month = substr($mytime, 0, 6);
//                    self::getNum($uid, $month, $day,$i);
//                }
            }
            return $i;
        }catch (\Exception $e){
            return error($e->getMessage());
        }
    }

}
